package org.shan.hangtian;

import com.mlnx.common.utils.MyLog;

import org.shan.hangtian.properties.HangtianProperties;
import org.shan.hangtian.server.handler.DataDecode;
import org.shan.hangtian.server.handler.DataEncode;
import org.shan.hangtian.server.handler.DataSaveHandle;
import org.shan.hangtian.server.handler.EventHandle;
import org.shan.hangtian.server.session.SessionManager;
import org.shan.hangtian.tp.HangtianPacket;
import org.shan.hangtian.tp.RunMode;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.IdleStateHandler;

/**
 * Created by amanda.shan on 2020/10/6.
 */
public class DeviceClient implements DeviceControl {

    private MyLog log = MyLog.getLog(getClass());

    private EventLoopGroup group = new NioEventLoopGroup();

    private ChannelFuture future;
    private Bootstrap bootstrap;

    private boolean run;

    @Override
    public void start() throws InterruptedException {

        while (true) {
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY, true)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline p = ch.pipeline();
                            //p.addLast(new LoggingHandler(LogLevel.INFO));
                            ch.pipeline().addLast(new IdleStateHandler(HangtianProperties.getInstance().getTimeOut(),
                                    0, 0,
                                    TimeUnit.SECONDS));
                            ch.pipeline().addLast(new EventHandle());
                            ch.pipeline().addLast(new DataSaveHandle());
                            ch.pipeline().addLast(new DataDecode());
                            ch.pipeline().addLast(new DataEncode());
                        }
                    });

            try {
                future = b.connect(HangtianProperties.getInstance().getIp(),
                        HangtianProperties.getInstance().getPort()).sync();
                future.channel();
                run = true;
                break;
            } catch (Exception e) {
                log.error(e, "连接失败");
                Thread.sleep(1000);
            }
        }
    }

    @Override
    public void stop() {

        future.channel().close();
        run = false;
    }

    @Override
    public boolean isRun() {
        return run;
    }

    public static void main(String[] args) throws Exception {
        DeviceControl deviceControl = new DeviceClient();

        deviceControl.start();

        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                Channel onlineChannel = SessionManager.getInstance().getOnlineChannel();

                if (onlineChannel != null) {
                    onlineChannel.writeAndFlush(HangtianPacket.changeMusic(RunMode.MODE_1, (byte) 1));
                }
            }
        }, 0, 1000);

        SessionManager.getInstance().setSessionLis(new SessionManager.SessionLis() {
            @Override
            public void online() {
                System.out.println("在线");
            }

            @Override
            public void offline() {
                System.out.println("离线");
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            deviceControl.start();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
            }

            @Override
            public void modeChange(RunMode runMode) {
                System.out.println("当前模式: " + runMode);
            }
        });
    }
}
